package belf.migrate.engine.job.structure.helper;

import belf.migrate.api.common.DatabaseCompatibility;
import belf.migrate.api.common.DatabaseIdentifier;
import belf.migrate.api.model.QualifiersModel;
import belf.migrate.api.type.DbObjectType;
import belf.migrate.api.util.FieldCase;
import belf.migrate.api.util.QualifiedType;
import org.apache.commons.lang3.StringUtils;

/**
 * 大模型提示词辅助类
 */
public class PromtHelper {
    /**
     * 构造SQL转换的个性化条件
     * @param sourceCatalog 源端数据库类型，取值参考{@link DatabaseIdentifier}
     * @param sinkCatalog 目标端数据库类型，取值参考{@link DatabaseIdentifier}
     * @param sinkSchema 目标端数据库的schema
     * @param sinkQualifiersModel 目标端数据库的SQL语句的个性化设置
     * @param objectType 本次转换的SQL对象类型，取值参考{@link DbObjectType}
     * @return
     */
    public static String requirement(String sourceCatalog,
                              String sinkCatalog,
                              String sinkSchema,
                              QualifiersModel sinkQualifiersModel,
                                     DbObjectType objectType) {
        StringBuilder sb = new StringBuilder();
        sb.append(fieldCase(sinkQualifiersModel));

        String quotation = quote(sinkQualifiersModel, sourceCatalog, sinkCatalog);
        if (StringUtils.isNotEmpty(quotation)) {
            sb.append(quotation);
        }
        String schemaRequire = schema(sinkSchema, objectType);
        if (StringUtils.isNotEmpty(schemaRequire)) {
            sb.append(schemaRequire);
        }
        String connectionSymbol = connectionSymbol(sinkQualifiersModel);
        if (StringUtils.isNotEmpty(connectionSymbol)) {
            sb.append(connectionSymbol);
        }
        //如果目标端非MySQL兼容的数据库，对于函数和存储过程，DECLARE一般要放到CREATE和BEGIN之间
        if (!(DatabaseCompatibility.name(sinkSchema).equals("MySQL"))) {
            if (objectType == DbObjectType.PROCEDURE
                    || objectType == DbObjectType.FUNCTION) {
                sb.append("\n如果有DECLARE语句，需要提到BEGIN语句之前；");
            }
        }
        return sb.toString();
    }

    /**
     * 大小写转换要求
     * @param sinkQualifiersModel
     * @return
     */
    public static String fieldCase(QualifiersModel sinkQualifiersModel) {
        switch (sinkQualifiersModel.getFieldCase()) {
            case LOWERCASE:
                return "转换要求：\nSQL语句中的标识符全部改为小写；";
            case UPPERCASE:
                return "转换要求：\nSQL语句中的标识符全部改为大写；";
            default:
                return "转换要求：";
        }
    }

    /**
     * 表示名称是否加引号
     * @param sinkQualifiersModel
     * @param sourceCatalog
     * @param sinkCatalog
     * @return
     */
    public static String quote(QualifiersModel sinkQualifiersModel, String sourceCatalog, String sinkCatalog) {
        if (StringUtils.isEmpty(sinkQualifiersModel.getLeftQuote())) {
            return null;
        }
        if (sinkQualifiersModel.getLeftQuote().equals("\"")) {
            if (sourceCatalog.equals(DatabaseIdentifier.SQLSERVER)) {
                return "\n所有标识名称（包括模式名、表名、视图名、字段名等）的方括号替换为双引号；";
            } else {
                return "\n给所有标识名称（包括模式名、表名、视图名、字段名等）加上双引号；";
            }
        }
        return null;
    }

    /**
     * 是否要添加schema前缀
     * @param sinkSchema
     * @return
     */
    public static String schema(String sinkSchema, DbObjectType objectType) {
        if (StringUtils.isEmpty(sinkSchema)) {
            return null;
        }
        String objectName = "";
        if (objectType == DbObjectType.PROCEDURE
                || objectType == DbObjectType.FUNCTION) {
            objectName = objectType.chineseName() + "名称、";
        }
        String result = String.format("\n没有模式前缀的%s表名和视图名前面要加上模式名称%s；",
                objectName,
                sinkSchema);

        return result;
    }

    public static String connectionSymbol(QualifiersModel sinkQualifiersModel) {
        if (sinkQualifiersModel.getQualifiedType() == QualifiedType.COLON) {
            return "\n模式名称和表名、视图名之间用冒号连接；";
        }
        return null;
    }
}
